home *** CD-ROM | disk | FTP | other *** search
/ PC World 2006 December / PCWorld_2006-12_cd.bin / v cisle / ophcrack / ophcrack-win32-installer-2.3.3.exe / {app} / src / ophcrack.c < prev    next >
C/C++ Source or Header  |  2006-10-11  |  42KB  |  1,576 lines

  1. /*
  2.  
  3.     Ophcrack is a Lanmanager/NTLM hash cracker based on the faster time-memory
  4.     trade-off using rainbow tables. 
  5.     
  6.     Created with the help of: Maxime Mueller, Luca Wullschleger, Claude
  7.     Hochreutiner, Andreas Huber and Etienne Dysli.
  8.  
  9.     Copyright 2006 Philippe Oechslin, Cedric Tissieres
  10.  
  11.     Ophcrack is free software; you can redistribute it and/or modify
  12.     it under the terms of the GNU General Public License as published by
  13.     the Free Software Foundation; either version 2 of the License, or
  14.     (at your option) any later version.
  15.  
  16.     Ophcrack is distributed in the hope that it will be useful,
  17.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.     GNU General Public License for more details.
  20.  
  21.     You should have received a copy of the GNU General Public License
  22.     along with Ophcrack; if not, write to the Free Software
  23.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  24.  
  25.     This program is released under the GPL with the additional exemption 
  26.     that compiling, linking, and/or using OpenSSL is allowed.
  27. */
  28.  
  29. /* LanManager/NTLM password cracker using a Time-Memory Trade-Off */
  30.  
  31. /* 
  32.  * $Log: ophcrack.c,v $
  33.  * Revision 2.3.3 2006/10/11 tissieres
  34.  * save tables directory, error msg when no tables
  35.  *
  36.  * Revision 2.3.2 2006/10/10 tissieres
  37.  * Patched for FreeBSD
  38.  *
  39.  * Revision 2.3 2006/07/21 tissieres oechslin
  40.  * Support for Mac OS X Intel, NTLM tables, linear search, Windows preload, ...
  41.  *
  42.  * Revision 2.2 2006/03/20 tissieres oechslin dysli
  43.  * Support for extended charset, memory management
  44.  *
  45.  * Revision 2.1  2005/12/06 tissieres
  46.  * Added tables modification feature, readahead
  47.  *
  48.  * Revision 2.0  2005/03/24  tissieres
  49.  * Modified for GUI
  50.  *
  51.  * Revision 1.1  2004/09/13 14:26:02  oechslin
  52.  * Fixed bug in -q option
  53.  *
  54.  * Revision 1.0  2004/07/10 19:06:46  oechslin
  55.  * Initial revision
  56.  *
  57.  *
  58.  */
  59.  
  60.  
  61. #ifdef HAVE_CONFIG_H
  62. #include "config.h"
  63. #endif
  64. #include <stdio.h>
  65. #include <stdlib.h>
  66. #include <unistd.h>
  67. #include <string.h>
  68. #include <ctype.h>
  69. #ifndef WIN32
  70. #include <sys/times.h>
  71. #include <sys/mman.h>
  72. /* On *BSD, MAP_ANON is used instead of MAP_ANONYMOUS */
  73. #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
  74. #define MAP_ANONYMOUS MAP_ANON
  75. #endif
  76. #if HAVE_SYS_SYSINFO_H
  77. #include <sys/sysinfo.h>
  78. #elif HAVE_SYS_SYSCTL_H
  79. #include <sys/sysctl.h>
  80. #endif
  81. #if HAVE_FCNTL_H
  82. #include <fcntl.h>
  83. #endif
  84. #else /* WIN32 */
  85. #include <sys/time.h>
  86. #include <windows.h>
  87. #endif /* WIN32 */
  88. #include <sys/stat.h>
  89.  
  90.  
  91. #include "make_hash.h"
  92. #include "make_redux.h"
  93. #include "ophcrack.h"
  94.  
  95. #ifdef WIN32
  96. #define bzero(p, l) memset(p, 0, l)
  97. #endif /* WIN32 */
  98.  
  99. #define RAM_FOR_SYSTEM 150 //amount of ram left for the system
  100. #define NB_CHECKPOINTS 2
  101.  
  102. /* command line options */
  103. int magic_chains = 0,
  104.   stats = 0,
  105.   verbose = 0,
  106.   batch_mode = 0,
  107.   batch_tables = 1,
  108.   quiet = 0,
  109.   ident_col = 99999,
  110.   cols = 0,
  111.   offset = 0,
  112.   first_table = 0,
  113.   last_table = 20,
  114.   chkpt1 = -1,
  115.   chkpt2 = -1;
  116.  
  117. int checkpoint_value[2];
  118.  
  119. int STOP = 0,
  120.   open_tables = 0,
  121.   last_table_save,
  122.   batch_tables_save,
  123.   table_type = -1,
  124.   chars_size = -1;
  125.  
  126. unsigned char 
  127.   lm_hash1[MAX_HASH+1][8]={{0}}, 
  128.   lm_hash2[MAX_HASH+1][8]={{0}},
  129.   nt_hash[MAX_HASH+1][16]={{0}}, 
  130.   empty_hash[8]={0xaa,0xd3,0xb4,0x35,0xb5,0x14,0x04,0xee},
  131.   empty_nt_hash[16]={0x31,0xd6,0xcf,0xe0,0xd1,0x6a,0xe9,0x31,0xb7,0x3c,0x59,0xd7,0xe0,0xc0,0x89,0xc0};
  132.  
  133. int to_go, hashes=0, n=0, done1[MAX_HASH+1]={0},done2[MAX_HASH+1]={0}, userid[MAX_HASH+1], done_nt[MAX_HASH+1]={0};
  134.  
  135. char directory[128], info[MAX_HASH+1][64]={{0}}, password[MAX_HASH+1][16]={{0}}, 
  136.     password1[MAX_HASH+1][8]={{0}}, password2[MAX_HASH+1][8]={{0}}; 
  137.  
  138. char crack_type[] = "LM";
  139. int crack_type_num = 0;
  140.  
  141. #ifndef WIN32
  142. FILE *startfile[20],*endfile[20],*indexfile[20];
  143. #else
  144. HANDLE startfile[20], endfile[20], indexfile[20];
  145. unsigned char *startbuff[20],*endbuff[20],*indexbuff[20] = {0};
  146. #endif
  147. int F_INDEX=0, F_START=0, F_END=0;
  148.  
  149. unsigned long long int offset_nt[] = {0ULL, 95ULL, 9120ULL, 866495ULL, 
  150.                    82317120ULL, 7820126495ULL, 742912017120ULL,
  151.                    4264526623328ULL};
  152. extern unsigned char nt_chars_low36[];
  153. extern unsigned char nt_chars_alphanum62[];
  154. extern unsigned char nt_chars_ext95[];
  155.  
  156. /* statistics */
  157. int n_search = 0,
  158.   n_fseek = 0,
  159.   n_hashredux = 0,
  160.   n_false = 0,
  161.   n_false_redux = 0,
  162.   n_match = 0,
  163.   n_loop = 0,
  164.   n_found = 0,
  165.   n_cp_false = 0;
  166.  
  167. struct tms n_times;
  168. int ticks;
  169. clock_t n_start_time, laps_time; 
  170.  
  171. unsigned long int size_to_clean = 0;
  172.  
  173. #ifdef WIN32
  174. char *
  175. strsep(char** stringp, const char* delim)
  176. {
  177.     char *s;
  178.     const char *spanp;
  179.     int c, sc;
  180.     char *tok;
  181.  
  182.     if ((s = *stringp) == NULL)
  183.         return (NULL);
  184.     for (tok = s;;) {
  185.         c = *s++;
  186.         spanp = delim;
  187.         do {
  188.             if ((sc = *spanp++) == c) {
  189.                 if (c == 0)
  190.                     s = NULL;
  191.                 else
  192.                     s[-1] = 0;
  193.                 *stringp = s;
  194.                 return (tok);
  195.             }
  196.         } while (sc != 0);
  197.     }
  198.     /* NOTREACHED */
  199. }
  200.  
  201. #endif
  202.  
  203.  
  204. /* void usage(char *name)
  205. {
  206.     printf("usage %s [-pvsb -d directory -f first -i row -l last -n tables] -t columns lmhash[:nthash]ªhash_file_name\n",name);
  207.     printf("      -d directory where tables saved\n");
  208.     printf("      -t columns per table\n");
  209.     printf("      -o table offset (if not equal to t)\n");
  210.     printf("      -i appliy identical redux starting at this column \n");
  211.     printf("      -v verbose mode\n");
  212.     printf("      -s generate statistics\n");
  213.     printf("      -q quiet (no progress indication)\n");
  214.     printf("      -f first table (default 0)\n");
  215.     printf("      -l last table (default 2^31-1)\n");
  216.     printf("      -n number of tables to use at a time\n");
  217.     printf("\n\n");
  218.     printf("  Hashes can be provided in the following hex formats:\n");
  219.     printf("  lmhash\n");
  220.     printf("  lmhash:nthash\n");
  221.     printf("  username:userid:lmhash:nthash:other fieds (as provided by pwdump)\n");
  222.     printf("  or the name of a file containing such hashes, one on each line.\n\n");
  223.  
  224.     exit(-1);
  225. }
  226. */
  227.  
  228. /* void print_stats() {
  229.   clock_t t;
  230.  
  231.   t = times(&n_times);
  232.   printf("\nStatistics: \n hash-redux calculations: %d\n",
  233.      n_hashredux);
  234.   printf(" endpoint searched %d\n fseek operations %d\n",
  235.      n_search, n_fseek);
  236.   printf(" matches found %d\n false alarms %d\n",
  237.      n_match,
  238.      n_false);
  239.   printf(" hash-redux operations per false alarms %d\n",
  240.      (n_false? n_false_redux/n_false: 0));
  241.   printf(" time elapsed %5.2fs\n\n", 
  242.      (float)(t-n_start_time)/ ticks );
  243. }
  244. */
  245.  
  246. void init_stats() {
  247.   n_hashredux=0;
  248.   n_search=0;
  249.   n_fseek=0;
  250.   n_false=0;
  251.   n_false_redux=0;
  252.   n_match=0;
  253. #ifndef WIN32
  254.   n_start_time = times(&n_times);
  255. #else /* WIN32 */
  256.   n_start_time = clock(); 
  257. #endif /* WIN32 */
  258. }
  259.  
  260.  
  261.  
  262. /* Open all the files  
  263.    =================== */
  264. int open_files() 
  265. {
  266.   unsigned char filename[256];
  267.  
  268.   int table;
  269.   first_table=0; 
  270. #ifdef WIN32
  271.   int error;
  272. #endif 
  273.  
  274.   /* for all available tables */
  275.   for (table=first_table; table<=last_table; table++) {
  276.  
  277.     /* end points */
  278.     sprintf((char *)filename,"%s/table%d.bin",directory,table);
  279. #ifndef WIN32
  280.     if (!(endfile[table]=fopen((char *)filename,"r"))) {
  281. #else
  282.     endfile[table]= CreateFile(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING,
  283.                                 FILE_FLAG_SEQUENTIAL_SCAN, 0);
  284.     if (GetLastError()) {
  285. #endif
  286.     last_table = table-1;
  287.     break; /* all tables searched */
  288.     }        
  289.  
  290.     /* starting points */
  291.     sprintf((char *)filename,"%s/table%d.start",directory,table);
  292. #ifndef WIN32
  293.     if (!(startfile[table]=fopen((char *)filename,"r")))
  294. #else
  295.     startfile[table]= CreateFile(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING,
  296.                                 FILE_FLAG_SEQUENTIAL_SCAN, 0);
  297.     if (GetLastError()) 
  298. #endif
  299.       g_print ("cannot open table file");
  300.  
  301.     /* index table */
  302.     sprintf((char *)filename,"%s/table%d.index",directory,table);
  303. #ifndef WIN32
  304.     if (!(indexfile[table]=fopen((char *)filename,"r")))
  305. #else
  306.     indexfile[table]= CreateFile(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING,
  307.                                 FILE_FLAG_SEQUENTIAL_SCAN, 0);
  308.     if (GetLastError()) 
  309. #endif
  310.       g_print ("cannot open index file");
  311.   }
  312.  
  313.   if (table != first_table) {
  314.     //if (verbose) printf(" found tables %d through %d\n",first_table, last_table);
  315.     open_tables = 1;
  316.     last_table_save = last_table;
  317.     batch_tables_save = batch_tables;
  318.  
  319.     return 1;
  320.   } else {
  321.     printf(" found no tables!\n");
  322.     return 0;
  323.   }
  324. }
  325.  
  326. int close_files() 
  327. {
  328.   int table;
  329. #ifdef WIN32
  330.   int error;
  331. #endif 
  332.  
  333.   batch_tables = batch_tables_save;
  334.   last_table = last_table_save;
  335.   first_table = 0;
  336.   open_tables = 0;
  337.  
  338.   /* for all available tables */
  339.   for (table=first_table; table<=last_table; table++) {
  340.  
  341. #ifndef WIN32
  342.     fclose(endfile[table]);
  343.     fclose(startfile[table]);
  344.     fclose(indexfile[table]);
  345. #else
  346.     CloseHandle(endfile[table]);
  347.     CloseHandle(startfile[table]);
  348.     CloseHandle(indexfile[table]);
  349.       if (F_START && startbuff[table]) {
  350.     free(startbuff[table]);
  351.     startbuff[table] = 0;
  352.       }
  353.       if (F_END && endbuff[table]){
  354.     free(endbuff[table]);
  355.     endbuff[table] = 0;
  356.       }
  357.       if (F_INDEX && indexbuff[table]){
  358.     free(indexbuff[table]);
  359.     indexbuff[table] = 0;
  360.       }
  361. #endif
  362.   }
  363.   F_INDEX=0; F_START=0; F_END=0;
  364.   return 1;  
  365. }
  366.  
  367. int unbin95(unsigned int input, unsigned char *output) {
  368.  
  369.   int i = 0;
  370.   for (i=4; i>=0; i--) {
  371.     output[i]=nt_chars_ext95[input%95];
  372.     input/=95;
  373.   }
  374.   return 1;
  375. }
  376.  
  377. unsigned long long int bin43(unsigned char *input) {
  378.   unsigned long long int sum = 0;
  379.   int i,l;
  380.  
  381.   l = (int) strlen((char *)input);
  382.  
  383.   if (l<7)
  384.     for (i=0; i<l && i<6; i++)  
  385.       sum = sum*95 + (unsigned long long int)(strchr((char *)nt_chars_ext95,input[i]) - (char*)nt_chars_ext95); 
  386.   
  387.   else if (l==7)
  388.     for (i=0; i<7; i++) 
  389.       sum = sum*62 + (unsigned long long int)(strchr((char *)nt_chars_alphanum62,input[i]) - (char*)nt_chars_alphanum62); 
  390.   
  391.   else if (l==8)
  392.     for (i=0; i<8; i++) 
  393.       sum = sum*36 + (unsigned long long int)(strchr((char *)nt_chars_low36,input[i]) - (char*)nt_chars_low36);
  394.   
  395.   sum += offset_nt[l-1];
  396.  
  397.   
  398.   return sum;
  399. }
  400.  
  401.  
  402. /* Find a end of chain in a table and return the corresponding
  403.    start of chain using three files: index, end and start 
  404.    ================================================================
  405. */
  406.  
  407. int binsearch(int table, char *pw, char *startpw)
  408. {
  409.   
  410.   if (!crack_type_num) { //LM CRACK
  411.     int i,l,l2;
  412.     unsigned int prefix,start,offset;
  413.     unsigned short int postfix;
  414.     unsigned short int p1[200];
  415.     int high,low;
  416.     char *p;
  417. #ifdef WIN32
  418.     DWORD dwRead;
  419.     int* p_index = NULL;
  420.     int* p_start = NULL;
  421.     unsigned short int* p_end = NULL;
  422. #else
  423.     int dwRead;
  424. #endif
  425.     
  426.     
  427.     l2 = strlen(pw);
  428.     
  429.     /*calculate prefix from first 4 bytes */
  430.     prefix=0;
  431.     l=(l2<4 ? l2 : 4); 
  432.     offset=chars_size*chars_size*chars_size*chars_size;
  433.     for (i=0; i<4; i++) {
  434.       p=strchr((char *)charset,pw[i]);
  435.       if (i< l) prefix=prefix*chars_size+p-(char*)charset;
  436.       else {prefix+=offset;offset/=chars_size;}
  437.     }
  438.     //g_print("\nbinsearch: prefix %u\n",prefix);
  439.     /*calculate postfix from last 3 bytes */
  440.     postfix=0;
  441.     l=(l2>4 ? l2-4 : 0); offset=chars_size*chars_size*chars_size;
  442.     for (i=0; i<3; i++) {
  443.       p=strchr((char *)charset,pw[i+4]);
  444.       if (i< l) postfix=postfix*chars_size+p-(char*)charset;
  445.       else { postfix+=offset;offset/=chars_size; }
  446.     }
  447.     //g_print("binsearch: postfix %hu\n",postfix);
  448.     
  449.     /* look-up range for this prefix in the index */
  450. #ifndef WIN32
  451.     fseek(indexfile[table],4*prefix,SEEK_SET);
  452.     fread(&low,sizeof(low),1,indexfile[table]);
  453. #else
  454.     if (!F_INDEX) {
  455.       SetFilePointer(indexfile[table], 4*prefix, NULL, FILE_BEGIN);
  456.       ReadFile(indexfile[table], &low, sizeof(low), &dwRead, NULL);
  457.     } else {
  458.       p_index = (int*)(indexbuff[table]+4*prefix);
  459.       low = *p_index;
  460.     }
  461. #endif
  462.     n_fseek++;
  463.     //g_print("binsearch: low=%d\n",low);
  464.     if (low) {
  465. #ifndef WIN32
  466.       fread(&high,sizeof(high),1,indexfile[table]);
  467. #else
  468.       if (!F_INDEX) 
  469.     ReadFile(indexfile[table], &high, sizeof(high), &dwRead, NULL);
  470.       else {
  471.     p_index++;
  472.     high = *p_index;
  473.       }
  474. #endif
  475.       //g_print("binsearch: high=%d\n",high);
  476.       if (high) {
  477.     //g_print("binsearch: low=%d high=%d\n",low, high);
  478. #ifndef WIN32
  479.     fseek(endfile[table],(low)*2, SEEK_SET);
  480.     fread(&p1,sizeof(unsigned short int),(high-low),endfile[table]);
  481. #else
  482.     if (!F_END) {
  483.       SetFilePointer(endfile[table], (low)*2, NULL,FILE_BEGIN);
  484.       ReadFile(endfile[table], &p1, (high-low)*sizeof(unsigned short int), &dwRead, NULL);
  485.     } else {
  486.       //p_end = (unsigned short int*)(endbuff[table]+((low)*2));
  487.       memcpy(p1, (unsigned short int*) (endbuff[table]+((low)*2)), (high-low)*sizeof(unsigned short int));
  488.     }
  489. #endif
  490.     n_fseek++;
  491.     i=0;
  492.     while (i<(high-low)) {
  493.       if (p1[i]==postfix)
  494.         break; /* found! */
  495.       else
  496.         i++;
  497.     }
  498.     if (i == (high-low)) return 0;
  499.       }
  500.     }      
  501.     
  502.     /* read start and change it to ascii: */
  503. #ifndef WIN32
  504.     fseek(startfile[table],(low+i)*4,SEEK_SET);
  505.     fread(&start,sizeof(start),1,startfile[table]);
  506. #else
  507.     if (!F_START) {
  508.       SetFilePointer(startfile[table], (low+i)*4, NULL, FILE_BEGIN);
  509.       ReadFile(startfile[table], &start, sizeof(start), &dwRead, NULL); 
  510.     } else {
  511.       p_start = (int*)(startbuff[table]+((low+i)*4));
  512.       start = *p_start;
  513.     }
  514. #endif
  515.     n_fseek++;
  516.     //  g_print("start = %d", start);
  517.     
  518.     /* Extract checkpoint from start */
  519.     checkpoint_value[0] = (start>>30) & 0x1;
  520.     checkpoint_value[1] = (start>>31) & 0x1;
  521.     
  522.     start &= 0x3FFFFFFF;
  523.     
  524.     startpw[6]=0;
  525.     startpw[7]=0;
  526.     for(i=5;i>=0;i--) {
  527.       startpw[i] = charset[start%36]; /* WARNING! change 36 into CHARS_SIZE */
  528.       start/=36;
  529.     }
  530.   } else { //NT CRACK
  531.  
  532.     int i,l,l2;
  533.     unsigned int prefix,start;
  534.     unsigned short int postfix;
  535.     unsigned short int p1[200];
  536.     unsigned long long int pw_bin;
  537.     int high,low;
  538.     char *p;
  539. #ifdef WIN32
  540.     DWORD dwRead;
  541.         int* p_index = NULL;
  542.     int* p_start = NULL;
  543.     unsigned short int* p_end = NULL;
  544. #else
  545.     int dwRead;
  546. #endif
  547.     
  548.     pw_bin = bin43((unsigned char *)pw);
  549.  
  550.     prefix = (unsigned int) (pw_bin >>18 & 0x00000000FFFFFFFF);
  551.     postfix = (unsigned short int) (pw_bin & 0x000000000000FFFF);
  552.  
  553.     /* look-up range for this prefix in the index */
  554. #ifndef WIN32
  555.     fseek(indexfile[table],4*prefix,SEEK_SET);
  556.     fread(&low,sizeof(low),1,indexfile[table]);
  557. #else
  558.     if (!F_INDEX) {
  559.       SetFilePointer(indexfile[table], 4*prefix, NULL, FILE_BEGIN);
  560.       ReadFile(indexfile[table], &low, sizeof(low), &dwRead, NULL);
  561.     } else {
  562.       p_index = (int*)(indexbuff[table]+4*prefix);
  563.       low = *p_index;
  564.     }
  565. #endif
  566.     n_fseek++;
  567.     //g_print("binsearch: low=%d\n",low);
  568.     if (low) {
  569. #ifndef WIN32
  570.       fread(&high,sizeof(high),1,indexfile[table]);
  571. #else
  572.       if (!F_INDEX) 
  573.     ReadFile(indexfile[table], &high, sizeof(high), &dwRead, NULL);
  574.       else {
  575.     p_index++;
  576.     high = *p_index;
  577.       }
  578. #endif
  579.       //g_print("binsearch: high=%d\n",high);
  580.       if (high) {
  581.     //g_print("binsearch: low=%d high=%d\n",low, high);
  582. #ifndef WIN32
  583.     fseek(endfile[table],(low)*2, SEEK_SET);
  584.     fread(&p1,sizeof(unsigned short int),(high-low),endfile[table]);
  585. #else
  586.     if (!F_END) {
  587.       SetFilePointer(endfile[table], (low)*2, NULL,FILE_BEGIN);
  588.       ReadFile(endfile[table], &p1, (high-low)*sizeof(unsigned short int), &dwRead, NULL);
  589.     } else {
  590.       //p_end = (unsigned short int*)(endbuff[table]+((low)*2));
  591.       memcpy(p1, (unsigned short int*) (endbuff[table]+((low)*2)), (high-low)*sizeof(unsigned short int));
  592.        }
  593. #endif
  594.     n_fseek++;
  595.     i=0;
  596.     while (i<(high-low)) {
  597.       if (p1[i]==postfix)
  598.         break; /* found! */
  599.       else
  600.         i++;
  601.     }
  602.     if (i == (high-low)) return 0;
  603.       }
  604.     }      
  605.     
  606.     /* read start and change it to ascii: */
  607. #ifndef WIN32
  608.     fseek(startfile[table],(low+i)*4,SEEK_SET);
  609.     fread(&start,sizeof(start),1,startfile[table]);
  610. #else
  611.     if (!F_START) {
  612.       SetFilePointer(startfile[table], (low+i)*4, NULL, FILE_BEGIN);
  613.       ReadFile(startfile[table], &start, sizeof(start), &dwRead, NULL); 
  614.     } else {
  615.       p_start = (int*)(startbuff[table]+((low+i)*4));
  616.       start = *p_start;
  617.     }
  618. #endif
  619.     n_fseek++;
  620.     //  g_print("start = %d", start);
  621.     
  622.     startpw[5]=0;
  623.     startpw[6]=0;
  624.     startpw[7]=0;
  625.     unbin95(start, (unsigned char *)startpw);
  626.  
  627.  
  628.   }
  629.   return 1;
  630. }
  631.  
  632.   
  633. /* Find the password corresponing to HASH in a given table, at a given
  634.    column and starting with a given reduction function
  635.    =================================================== */
  636.  
  637. int find(unsigned char *hash, char *found, int col, int table)
  638. {
  639.   if (!crack_type_num) { // LM CRACK
  640.     unsigned char h[8];
  641.     static char pw[8], start[8];
  642.     static int i,l;
  643.     int checkpoint_found[2]={0};
  644.     
  645.     //g_print("\nfind: col=%d table=%d\n",col,table);
  646.     
  647.     set_redux(col, table);
  648.     
  649.     /* advance to end of chain */
  650.     
  651.     /* we can save this work if we are in parallel mode, above ident_redux and
  652.      * not in the first table and doing the tree-table optimization... */
  653.     
  654.     if (table==first_table || col < ident_col) {
  655.       make_redux(hash,(unsigned char *)pw);
  656.       //g_print("find: %d,%s ",n_redux,pw);
  657.       for (l=1; l<cols-col; l++) {
  658.     make_hash((unsigned char *)pw,h);
  659.     next_redux();
  660.     make_redux(h,(unsigned char *)pw);
  661.     //g_print("%d,%s ",n_redux,pw);
  662.     if ((chkpt1 != -1) && (chkpt2 !=-1)) {
  663.       if ((col+l+1) == chkpt1) 
  664.         checkpoint_found[0] = pw[0] & 0x1;
  665.       if ((col+l+1) == chkpt2)
  666.         checkpoint_found[1] = pw[0] & 0x1;
  667.     }
  668.       }
  669.       n_hashredux+=l;
  670.       //g_print("%-7.7s\n",pw);
  671.       //g_print("find: n_hashredux=%d l=%d\n",n_hashredux,l);
  672.     }
  673.     
  674.     while (gtk_events_pending ()) 
  675.       gtk_main_iteration ();
  676.     
  677.     /* look up the end in the table and get the start */
  678.     if (binsearch(table,pw,start)) {
  679.       n_match++;
  680.       if ((chkpt1 != -1) && (chkpt2 !=-1)) {
  681.     if (!((checkpoint_value[0] == checkpoint_found[0])
  682.           && (checkpoint_value[1] == checkpoint_found[1]))) {
  683.       n_cp_false++;
  684.       return 0;
  685.     }
  686.       }
  687.       
  688.       set_redux(0, table);
  689.       /* advance to the colunm that we are exploring */
  690.       for (i=l; i<=cols-1; i++) {
  691.     make_hash((unsigned char *)start,h);
  692.     make_redux(h,(unsigned char *)start); 
  693.     next_redux();
  694.     n_hashredux++;
  695.       }
  696.       make_hash((unsigned char *)start,h);
  697.       /* check if we get the same hash: */
  698.       if (!memcmp(&h,hash,sizeof(h))) {
  699.     strncpy(found,start,8);
  700.     //g_print("find: found in table %d\n",table);
  701.     return 1;
  702.       }
  703.       else {
  704.     /* false alarm! */
  705.     n_false++;
  706.     n_false_redux += cols-l;
  707.       }
  708.     }
  709.   } else { //NT CRACK
  710.  
  711.     unsigned char h[16];
  712.     static char pw[16], start[16];
  713.     static int i,l;
  714.     
  715.     set_redux(col, table);
  716.     
  717.     /* advance to end of chain */
  718.     
  719.     if (table==first_table || col < ident_col) {
  720.       make_redux(hash,(unsigned char *)pw);
  721.       //g_print("find: %d,%s ",n_redux,pw);
  722.       for (l=1; l<cols-col; l++) {
  723.     make_nthash(pw,(char *)h);
  724.     next_redux();
  725.     make_redux(h,(unsigned char *)pw);
  726.     //g_print("%d,%s ",n_redux,pw);
  727.       }
  728.       n_hashredux+=l;
  729.       //g_print("%-7.7s\n",pw);
  730.       //g_print("find: n_hashredux=%d l=%d\n",n_hashredux,l);
  731.     }
  732.     
  733.     while (gtk_events_pending ()) 
  734.       gtk_main_iteration ();
  735.     
  736.     /* look up the end in the table and get the start */
  737.     if (binsearch(table,pw,start)) {
  738.       n_match++;
  739.       
  740.       set_redux(0, table);
  741.       /* advance to the colunm that we are exploring */
  742.       for (i=l; i<=cols-1; i++) {
  743.     make_nthash(start,(char *)h);
  744.     make_redux(h,(unsigned char *)start); 
  745.     next_redux();
  746.     n_hashredux++;
  747.       }
  748.       make_nthash(start,(char *)h);
  749.       /* check if we get the same hash: */
  750.       if (!memcmp(&h,hash,sizeof(h))) {
  751.     strncpy(found,start,16);
  752.     //g_print("find: found in table %d\n",table);
  753.     return 1;
  754.       }
  755.       else {
  756.     /* false alarm! */
  757.     n_false++;
  758.     n_false_redux += cols-l;
  759.       }
  760.     }
  761.     
  762.   }
  763.   return 0;
  764. }
  765.  
  766.  
  767. /* Read two halfs of LMHash and possibly NTHash and info from string */
  768. int get_hashes(unsigned char lmhash_1[], unsigned char lmhash_2[], 
  769.            char nthash[], unsigned char *info, int *userid, 
  770.            char *password1, char *password2, char *password, 
  771.            int *done1, int *done2, char *h)
  772. {
  773.   /* following formats are supported:
  774.      lmhash
  775.      lmhash:nthash
  776.      username:userid:lmhash:nthash:passwd1:passwd2:passwd (like pwdump2)
  777.   */
  778.   
  779.   unsigned int i,k,l;
  780.   char *p[8] = {0};
  781.   unsigned char *tmp;
  782.   l=0;
  783.   p[l]=strsep(&h,":");
  784.   while (l<8){
  785.     l++;
  786.     if (!(p[l]=strsep(&h,":")) ) break;
  787.   }
  788.   if (l==7) {
  789.     if (strcmp(p[0],"")) strncpy((char *)info,p[0],64);
  790.     if (strcmp(p[1],"")) *userid = atoi(p[1]);
  791.     if (!strcmp(p[2],"NO PASSWORD*********************")) {
  792.       memcpy(lmhash_1, empty_hash, 8);
  793.       memcpy(lmhash_2, empty_hash, 8);
  794.     }
  795.     else 
  796.       for (i=0; i<8; i++) {
  797.     if (sscanf(p[2]+2*i,"%2x",&k) !=1 ) 
  798.       return 0;
  799.     lmhash_1[i]=(unsigned char)k;
  800.     
  801.     if (sscanf(p[2]+2*i+16,"%2x",&k) !=1 ) 
  802.       return 0;
  803.     lmhash_2[i]=(unsigned char)k;
  804.       }
  805.     
  806.     if (strcmp(p[3],"")){
  807.       if (!strcmp(p[3],"NO PASSWORD*********************"))
  808.     memcpy(nthash, empty_nt_hash, 16);
  809.       else 
  810.     for (i=0;i<16;i++)
  811.       if (sscanf(p[3]+2*i,"%2hhx",(unsigned char *)&nthash[i])!=1) 
  812.         return 0;
  813.     } else 
  814.       nthash[0]=0;
  815.     /* thanks to BaLP */
  816.     if (strcmp(p[4],"")) {
  817.       strncpy(password1, p[4], strlen(p[4]));
  818.       for (tmp = (unsigned char *)password1; (*tmp = (*tmp == 193U ? ':' : *tmp)); ++tmp);
  819.       *done1=1;
  820.     }
  821.     if (strcmp(p[5], "")) {
  822.       strncpy(password2, p[5], strlen(p[5]));
  823.       for (tmp = (unsigned char *)password2; (*tmp = (*tmp == 193U ? ':' : *tmp)); ++tmp);
  824.       *done2=1;
  825.     }
  826.     strncpy(password, p[6], strlen(p[6]));
  827.     for (tmp = (unsigned char *)password; (*tmp = (*tmp == 193U ? ':' : *tmp)); ++tmp);
  828.  
  829.  
  830.   } else {
  831.     
  832.     if (!strcmp(p[0],"NO PASSWORD*********************")) {
  833.       memcpy(lmhash_1, empty_hash, 8);
  834.       memcpy(lmhash_2, empty_hash, 8);
  835.     }
  836.     else 
  837.       for (i=0; i<8; i++) {
  838.     if (sscanf(p[0]+2*i,"%2x",&k) !=1 ) 
  839.       return 0;
  840.     lmhash_1[i]=(unsigned char)k;
  841.     
  842.     if (sscanf(p[0]+2*i+16,"%2x",&k) !=1 ) 
  843.       return 0;
  844.     lmhash_2[i]=(unsigned char)k;
  845.       }      
  846.     
  847.     if (l>1) {
  848.       
  849.       if (strcmp(p[1],"")){
  850.     if (!strcmp(p[1],"NO PASSWORD*********************"))
  851.       memcpy(nthash, empty_nt_hash, 16);
  852.     else 
  853.       for (i=0;i<16;i++)
  854.         if (sscanf(p[1]+2*i,"%2hhx",(unsigned char *)&nthash[i])!=1) 
  855.           return 0;
  856.       }
  857.     }
  858.   }
  859.   
  860.   return 1;
  861. }
  862.  
  863. int read_line(char *line) {
  864.   if (get_hashes(lm_hash1[hashes],lm_hash2[hashes],
  865.          (char *)nt_hash[hashes],(unsigned char *)info[hashes], &userid[hashes], 
  866.          password1[hashes], password2[hashes], 
  867.          password[hashes],&done1[hashes], &done2[hashes],line)) {
  868.     hashes++;
  869.     return 1;
  870.   } else {
  871.     return 0;
  872.   }
  873. }
  874.  
  875. int remove_line(int hash) {
  876.   int diff;
  877.  
  878.   diff=hashes-hash;
  879.   if (diff>0) {
  880.     memmove(lm_hash1[hash], lm_hash1[hash+1], diff*sizeof(lm_hash1[hash]));
  881.     memmove(lm_hash2[hash], lm_hash2[hash+1], diff*sizeof(lm_hash2[hash]));
  882.     memmove(nt_hash[hash], nt_hash[hash+1], diff*sizeof(nt_hash[hash]));
  883.     memmove(info[hash], info[hash+1], diff*sizeof(info[hash]));
  884.     memmove(&userid[hash], &userid[hash+1], diff*sizeof(&userid[hash]));
  885.     memmove(password1[hash], password1[hash+1], diff*sizeof(password1[hash]));
  886.     memmove(password2[hash], password2[hash+1], diff*sizeof(password2[hash]));
  887.     memmove(password[hash], password[hash+1], diff*sizeof(password[hash]));
  888.     memmove(&done1[hash], &done1[hash+1], diff*sizeof(&done1[hash]));
  889.     memmove(&done2[hash], &done2[hash+1], diff*sizeof(&done2[hash]));
  890.   }
  891.   hashes--;
  892. }
  893.  
  894. int resolve_nt_hash(char p1[], char p2[], char h[], char pw[])
  895. {
  896.   unsigned int i;
  897.   unsigned int k=0,l;
  898.   unsigned char md4[17],*p;
  899.   
  900.   bzero(pw,15);
  901.   strcpy(pw,p1);
  902.   strcpy(&pw[7],p2);
  903.   
  904.   md4[16]=0;
  905.   
  906.   for (i=0; i<16384; i++) {
  907.     l = k ^ i ^ (i>>1);
  908.     k = i ^ (i>>1);
  909.     p = (unsigned char *)pw; while ((l=l>>1)) p++;
  910.     *p=(*p>91?toupper(*p):tolower(*p));
  911.     make_nthash(pw,(char *)md4);
  912.     
  913.     if (!memcmp(md4,h,16)) {
  914.       return 1;
  915.     }
  916.   }
  917.   return 0;
  918. }
  919.  
  920.  
  921. /* Display password and progress indication */
  922. void display(int h, int k)
  923. {
  924.   int i;
  925.  
  926.   if (h==-1)
  927.     printf("%-32s : %-14s\n","username or lmhash","password");
  928.   if (h>= 0) {
  929.     if (info[h][0])
  930.       printf("%-32s : ",info[h]);
  931.     else {
  932.       for (i=0; i<8; i++) printf("%02hhx",lm_hash1[h][i]);
  933.       for (i=0; i<8; i++) printf("%02hhx",lm_hash2[h][i]);
  934.       printf(" : ");
  935.     }
  936.     if (resolve_nt_hash(password1[h],password2[h], (char *)nt_hash[h],password[h]) )
  937.       printf("%-14s    \n",password[h]);
  938.     else
  939.     printf("%-7s%-7s    \n",password1[h],password2[h]);
  940.   }
  941.  
  942.   if (!quiet) {
  943. #ifndef WIN32
  944.     laps_time = times(&n_times);
  945. #else /* WIN32 */
  946.     laps_time = clock();
  947. #endif /* WIN32 */
  948.     printf("[tables:%d-%d,%2d%% passwords:%d/%d  seconds/pw:%.2f]\r",
  949.        first_table,
  950.        last_table,
  951.        100-(100*k)/cols,
  952.        n_found, hashes,
  953.        (n_found?(float)(laps_time - n_start_time)/ticks/n_found:0));
  954.   }
  955. }
  956.  
  957. int read_file(char* filename) {
  958.   char c;
  959.   char *line;
  960.   int size = 199;
  961.   FILE *hash_file;
  962.   
  963.   clear_passwd_arrays();
  964.   
  965.   hashes = 0;  
  966.   n_found = 0;
  967.   
  968.   /* get hash from command line or from file: */
  969.   
  970.   if (!(hash_file=fopen(filename,"r"))) {
  971.     //g_print("%s is neither a valid hash or a filename\n\n\n",filename);
  972.     return 0;
  973.   }
  974.   line = malloc(size+1);
  975.  
  976.   /* Get hashes from file into table */
  977.   fgets(line, 199, hash_file);
  978.   if (line[strlen(line)-1] == '\n') line[strlen(line)-1] = 0; //remove newline
  979.   while (!feof(hash_file) && (hashes <MAX_HASH)) {
  980.     if (get_hashes(lm_hash1[hashes],lm_hash2[hashes],
  981.            (char *)nt_hash[hashes],(unsigned char *)info[hashes], &userid[hashes], 
  982.            password1[hashes], password2[hashes], 
  983.            password[hashes],&done1[hashes], &done2[hashes],line)) 
  984.       //printf("invalid hash found in hash file: %s\n",line);
  985.       //else
  986.       hashes++;
  987.     fgets(line, 199, hash_file);
  988.     if (line[strlen(line)-1] == '\n') line[strlen(line)-1] = 0;
  989.   }
  990.   if (hashes == MAX_HASH) 
  991.     show_error_max_hash();
  992.  
  993.   fclose(hash_file);
  994.   return hashes;
  995. }
  996.  
  997.  
  998. void clear_passwd_arrays(void) {
  999.   int i;
  1000.   
  1001.   for (i=0; i<hashes; i++) {
  1002.     bzero(info[i], sizeof(info[i]));
  1003.     bzero(lm_hash1[i], sizeof(lm_hash1[i]));
  1004.     bzero(lm_hash2[i], sizeof(lm_hash2[i]));
  1005.     bzero(nt_hash[i], sizeof(nt_hash[i]));
  1006.     userid[i]=0;
  1007.     bzero(password1[i], sizeof(password1[i]));
  1008.     bzero(password2[i], sizeof(password2[i]));
  1009.     bzero(password[i], sizeof(password[i]));
  1010.     done1[i]=0;
  1011.     done2[i]=0;
  1012.   }  
  1013. }
  1014.  
  1015. int auto_detect_tables(char *directory) {
  1016.   unsigned char filename[256];
  1017.   unsigned char configfilename[256];
  1018.   FILE *file;
  1019.   unsigned int buff;
  1020.   char *parameter;
  1021.   FILE *configfile;
  1022.   char *line = (char *)malloc(100*sizeof(char)); 
  1023.  
  1024.  
  1025.   /* test if we know the tables */
  1026.   sprintf((char *)filename,"%s/table0.bin",directory);
  1027.   if (file=fopen((char *)filename, "r")) {
  1028.     fread(&buff, sizeof(int), 1, file);
  1029.  
  1030.     switch(buff) {
  1031.       
  1032.     case 0x3cc21790 : table_type = 0; cols=10000; batch_tables=1; 
  1033.       last_table=3; offset=10000; break;
  1034.     case 0x0fa2031c : table_type = 1; cols=5000; offset = 10000;
  1035.       batch_tables = 1; last_table = 3; break;
  1036.     case 0x0e3402df : 
  1037.     case 0xc7ed7df5 :
  1038.       sprintf((char *)configfilename,"%s/tables.cfg",directory);
  1039.       if (!(configfile=fopen((char *)configfilename,"r"))) {
  1040.     return 0;
  1041.       }
  1042.       else {
  1043.     while( fgets(line, 99, configfile) != NULL ) {
  1044.       parameter = (char *)strsep(&line,"=");
  1045.       if (!strcmp(parameter, "table_type"))
  1046.         table_type = atoi(line);
  1047.       if (!strcmp(parameter, "cols"))
  1048.         cols = atoi(line);
  1049.       if (!strcmp(parameter, "offset"))
  1050.         offset = atoi(line);
  1051.       if (!strcmp(parameter, "chkpt1"))
  1052.         chkpt1 = atoi(line);
  1053.       if (!strcmp(parameter, "chkpt2"))
  1054.         chkpt2 = atoi(line);
  1055.       if (!strcmp(parameter, "crack_type"))
  1056.         strncpy(crack_type, line, 2);
  1057.     }
  1058.       }
  1059.       break;
  1060.     default: fclose(file); return 0; break;
  1061.     }
  1062.     fclose(file);
  1063.  
  1064.     return 1;
  1065.   } else return 0;
  1066.   
  1067. }
  1068.  
  1069. int find_tables() {
  1070. #ifdef WIN32
  1071.   strcpy(directory, "5000");
  1072. #else
  1073.   snprintf(directory, 127, "%s/5000", TDIR);
  1074. #endif
  1075.   if (access(directory, F_OK) == 0) {
  1076.     auto_detect_tables(directory);
  1077.   }
  1078.   else {
  1079. #ifdef WIN32
  1080.     strcpy(directory, "10000");
  1081. #else
  1082.     snprintf(directory, 127, "%s/10000", TDIR);
  1083. #endif
  1084.     
  1085.     if (access(directory, F_OK) == 0) {
  1086.       auto_detect_tables(directory);
  1087.     }
  1088.   }
  1089.   
  1090.   n_found = 0;
  1091.   
  1092.   if (!offset) offset=cols;
  1093.   
  1094. }
  1095.  
  1096. #ifndef WIN32
  1097. int clean_ram(unsigned long int size) {
  1098.   /* clean page cache (very dirty...) */
  1099.  
  1100.   unsigned long int i;
  1101.   char *ptr;
  1102.  
  1103.   show_clean_window();
  1104.   ptr = (char*)mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
  1105.   if (ptr!= MAP_FAILED) {
  1106.     for (i=0; i<size; ++i) {
  1107.       *(ptr + i) = 1;
  1108.     }
  1109.     munmap(ptr, size);
  1110.   }
  1111.   hide_readahead_window();
  1112.   return 0;
  1113. }
  1114. #endif
  1115.  
  1116. int evaluate_ram() {
  1117.     
  1118. #ifdef WIN32
  1119.   MEMORYSTATUS stat;
  1120.   DWORD filesize[3];
  1121. #else    
  1122.   struct stat buf;
  1123.   //struct sysinfo info;
  1124.   size_t filesize[3];
  1125.   int fd;
  1126. #endif
  1127. #ifdef HAVE_SYS_SYSINFO_H
  1128.   struct sysinfo info;
  1129. #elif defined(HAVE_SYS_SYSCTL_H)
  1130.   int mib[2] = {CTL_HW, HW_PHYSMEM}, mem;
  1131.   size_t len;
  1132. #endif
  1133.   long int totalram,freeram;
  1134.  
  1135.   /* calculate table size*/
  1136. #ifndef WIN32
  1137.   fd = fileno(indexfile[first_table]);
  1138.   fstat(fd, &buf);
  1139.   filesize[0] = (size_t)buf.st_size;
  1140.   fd = fileno(endfile[first_table]);
  1141.   fstat(fd, &buf);
  1142.   filesize[1] = (size_t)buf.st_size +filesize[0];
  1143.   fd = fileno(startfile[first_table]);
  1144.   fstat(fd, &buf);
  1145.   filesize[2] = (size_t)buf.st_size +filesize[1];
  1146. #else
  1147.   filesize[0] = GetFileSize(indexfile[first_table], NULL);
  1148.   filesize[1] = GetFileSize(endfile[first_table], NULL) + filesize[0];
  1149.   filesize[2] = GetFileSize(startfile[first_table], NULL) +filesize[1];
  1150. #endif   
  1151.   batch_tables=1;
  1152.   size_to_clean = (unsigned long int) filesize[2];
  1153.   
  1154.   /* retrieve system info */
  1155. #if HAVE_SYS_SYSINFO_H
  1156.   sysinfo(&info);
  1157.   totalram = (long int)info.totalram - RAM_FOR_SYSTEM*1024*1024;
  1158.   freeram = (long int)info.freeram;
  1159. #elif HAVE_SYS_SYSCTL_H
  1160.   len = sizeof(mem);
  1161.   if (sysctl(mib, 2, &mem, &len, NULL, 0) == 0) {
  1162.     totalram = mem - RAM_FOR_SYSTEM*1024*1024;
  1163.   } else {
  1164.     perror("sysctl");
  1165.     exit(-1);
  1166.   }
  1167.   
  1168.   mib[1] = HW_USERMEM;
  1169.   len = sizeof(mem);
  1170.   if (sysctl(mib, 2, &mem, &len, NULL, 0) == 0) {
  1171.     freeram = mem;
  1172.   } else {
  1173.     perror("sysctl");
  1174.     exit(-1);
  1175.   }
  1176. #elif defined(WIN32)
  1177.   GlobalMemoryStatus (&stat);
  1178.   totalram = 0;
  1179.   freeram = (long int)stat.dwAvailPhys;
  1180. #else
  1181. #error do not know how to get RAM information
  1182. #endif
  1183.  
  1184. #ifndef WIN32
  1185.   //g_print("%d%d%d %d %u %d %d\n", F_INDEX, F_END, F_START, batch_tables, batch_tables*filesize[2], freeram, totalram);
  1186.   if (totalram < freeram) totalram=freeram;
  1187.  
  1188.   if (size_to_clean > totalram)
  1189.     size_to_clean = totalram;
  1190.   while ((size_to_clean*batch_tables) < totalram) {
  1191.     batch_tables++;
  1192.   }
  1193.   if (batch_tables >1) batch_tables--;
  1194.   if (batch_tables > last_table +1)
  1195.     batch_tables = last_table+1;
  1196.   
  1197.   size_to_clean *= batch_tables;
  1198.   //g_print("%d%d%d %d %u %d %d\n", F_INDEX, F_END, F_START, batch_tables, batch_tables*filesize[2], freeram, totalram);
  1199.  
  1200.   /* clean ram */
  1201.   clean_ram(size_to_clean);
  1202.   
  1203.   /* reevaluate available ram */
  1204. #if HAVE_SYS_SYSINFO_H
  1205.   sysinfo(&info);
  1206.   freeram = (long int)info.freeram;
  1207. #elif HAVE_SYS_SYSCTL_H
  1208.   mib[0] = CTL_HW;
  1209.   mib[1] = HW_USERMEM;
  1210.   len = sizeof(mem);
  1211.   if (sysctl(mib, 2, &mem, &len, NULL, 0) == 0) {
  1212.     freeram = mem;
  1213.   } else {
  1214.     perror("sysctl");
  1215.     exit(-1);
  1216.   }
  1217. #else
  1218. #error do not know how to get RAM information
  1219. #endif
  1220. #endif
  1221.  
  1222. #if HAVE_READAHEAD
  1223.   if (freeram < size_to_clean) {
  1224.     if (filesize[0]>freeram) {
  1225.       F_INDEX=1; F_END = 0; F_START = 0; batch_tables = 1;
  1226.     }
  1227.     else if (filesize[1]>freeram) {
  1228.       F_INDEX=1; F_END = 1; F_START = 0; batch_tables = 1;
  1229.     }
  1230.     else {
  1231.       F_INDEX=1; F_END = 1; F_START = 1; batch_tables = 1;
  1232.     }
  1233.   } else {
  1234.     F_INDEX=1; F_END = 1; F_START = 1; batch_tables = 1;
  1235.     size_to_clean = (long int)filesize[2];
  1236.     
  1237.     while ((size_to_clean*batch_tables) < freeram) {
  1238.       batch_tables++;
  1239.     }
  1240.     if (batch_tables >1) batch_tables--;
  1241.   }
  1242.   //g_print("%d%d%d %d %u %d %d\n", F_INDEX, F_END, F_START, batch_tables, batch_tables*filesize[2], freeram, totalram);
  1243.  
  1244. #else /* no READAHEAD*/
  1245.  
  1246.   if (freeram < size_to_clean) {
  1247.     if (filesize[0]>freeram) {
  1248.       F_INDEX=0; F_END = 0; F_START = 0; batch_tables = 1;
  1249.     }
  1250.     else if (filesize[1]>freeram) {
  1251.       F_INDEX=1; F_END = 0; F_START = 0; batch_tables = 1;
  1252.     }
  1253.     else {
  1254.       F_INDEX=1; F_END = 1; F_START = 0; batch_tables = 1;
  1255.     } 
  1256.   } else {
  1257.     F_INDEX=1; F_END = 1; F_START = 1; batch_tables = 1;
  1258.     size_to_clean = (long int)filesize[2];
  1259.     while ((size_to_clean*batch_tables) < freeram) {
  1260.       batch_tables++;
  1261.     }
  1262.     if (batch_tables >1) batch_tables--;
  1263.   }
  1264.  
  1265.   //  if ((batch_tables ==1) && (2*size_to_clean < totalram)) batch_tables++;
  1266. #endif
  1267.  
  1268. }
  1269.  
  1270. #ifdef LIVECD
  1271. int init_livecd(char *dir) {
  1272.  
  1273.   bzero(directory, strlen(directory));
  1274.   strncpy(directory, dir, strlen(dir));
  1275.   cols = 10000;
  1276.   offset = 10000;
  1277.   first_table=0;
  1278.   last_table=3;
  1279.   batch_tables = 4;
  1280.   table_type = 0;
  1281.  
  1282.   activate_launch_toggle();
  1283.  
  1284. }
  1285. #endif
  1286.  
  1287.  
  1288. /* MAIN 
  1289.    ==== */
  1290.  
  1291. int main_cmd()
  1292.  
  1293. {
  1294.   extern int optind;
  1295.   extern char *optarg;
  1296.   int h, i, k, t, table, f_t, l_t;
  1297.   int display_step;
  1298.  
  1299.   /* disabled for GUI  
  1300.   while ((c=getopt(argc, argv, "qn:d:vt:o:si:f:l:"))>0) {
  1301.     switch ((char)c) {
  1302.     case 'd': strcpy(directory, optarg); break;
  1303.     case 't': cols = atoi(optarg); break;
  1304.     case 'o': offset = atoi(optarg); break;
  1305.     case 'i': ident_col = atoi(optarg); break;
  1306.     case 'v': verbose=1;break;
  1307.     case 's': stats = 1; init_stats(); break;
  1308.     case 'f': first_table = atoi(optarg); break;
  1309.     case 'l': last_table = atoi(optarg); break;
  1310.     case 'n': batch_tables = atoi(optarg); break;
  1311.     case 'q': quiet = 1; break;
  1312.     case '?': usage(argv[0]);break;
  1313.     }
  1314.   }
  1315.   */
  1316.   
  1317.   n_found=0;
  1318.  
  1319.   init_redux(offset,ident_col);
  1320.  
  1321.   /* find out how many ticks we have per second */
  1322. #ifndef WIN32
  1323.   ticks = sysconf(_SC_CLK_TCK); 
  1324. #else /* WIN32 */
  1325.   ticks = CLOCKS_PER_SEC; 
  1326. #endif /* WIN32 */
  1327.  
  1328.   /* open all table files */
  1329.   if (!open_tables)
  1330.     if (!open_files(directory)) return -2;
  1331.  
  1332.   //read_file - GUI
  1333.   to_go = 3*hashes;
  1334.   
  1335.   if (!strcmp(crack_type, "LM")) 
  1336.     crack_type_num=0;
  1337.   else
  1338.     crack_type_num=1;
  1339.  
  1340.   /* Eliminate empty ones: */
  1341.   for (i=0; i<hashes; i++) {
  1342.     if (!memcmp(lm_hash1[i],empty_hash,
  1343.         sizeof(lm_hash1[i]))) {
  1344.       strcpy(password1[i],"/EMPTY/");
  1345.       done1[i]=1;
  1346.     }
  1347.     if (!memcmp(lm_hash2[i],empty_hash,
  1348.         sizeof(lm_hash2[i]))) {
  1349.       done2[i]=1;
  1350.     }
  1351.     if (!memcmp(nt_hash[i], empty_nt_hash, sizeof(nt_hash[i])) || !strncmp((char *)nt_hash[i], "", 2)) {
  1352.       strcpy(password[i],"/EMPTY/");
  1353.       done_nt[i]=1;
  1354.     }
  1355.     if (done1[i])
  1356.       to_go--;
  1357.     if (done2[i])
  1358.       to_go--;
  1359.     if (done_nt[i])
  1360.       to_go--;
  1361.     if (done1[i] && done2[i] && done_nt[i])
  1362.       n_found++;
  1363.     if (!done1[i]) bzero(password1[i], sizeof(password1[i]));
  1364.     if (!done2[i]) bzero(password2[i], sizeof(password2[i]));
  1365.     if (!done_nt[i]) bzero(password[i], sizeof(password[i]));
  1366.  
  1367.   }
  1368.   fill_tree();
  1369.  
  1370.   if (!to_go)
  1371.     return(1);
  1372.   
  1373.   //g_print("togo: %d\n", to_go);
  1374.  
  1375.   /* search all passwords in all tables: */
  1376.   /* ==================================  */
  1377.  
  1378.   display_step = cols/100;
  1379.   /* for each batch: */
  1380.   f_t = first_table; l_t= last_table;
  1381.   
  1382.   evaluate_ram();
  1383.  
  1384.   init_stats();
  1385.  
  1386.   /*  g_print("cols %d, offset %d, f_t %d, l_t %d, chkpt1 %d, chkpt2 %d, batch %d, chars_size %d\n", cols, offset, f_t, l_t, chkpt1, chkpt2, batch_tables, chars_size);
  1387.   for (i=0; i<chars_size; i++)
  1388.     g_print("%c", charset[i]);
  1389.   g_print("\n");
  1390.   */
  1391.   for (t=f_t; t<= l_t; t+=batch_tables) {
  1392.  
  1393.     first_table = t;
  1394.     last_table = t+batch_tables-1>l_t? l_t : t+batch_tables-1;
  1395. #if HAVE_READAHEAD 
  1396.     if (t>f_t)
  1397.       clean_ram(size_to_clean);
  1398. #elif defined(WIN32)
  1399.     for (i=first_table-batch_tables; i<first_table && (i>-1); i++) {
  1400.       if (F_START && startbuff[i]) {
  1401.     free(startbuff[i]);
  1402.     startbuff[i] = 0;
  1403.       }
  1404.       if (F_END && endbuff[i]){
  1405.     free(endbuff[i]);
  1406.     endbuff[i] = 0;
  1407.       }
  1408.       if (F_INDEX && indexbuff[i]){
  1409.     free(indexbuff[i]);
  1410.     indexbuff[i] = 0;
  1411.       }
  1412.     }
  1413. #endif
  1414.  
  1415.     for (table=first_table; table<= last_table; table++) 
  1416.  
  1417. #if HAVE_READAHEAD      
  1418.       /* readahead, preload the table in file cache
  1419.        * ED 28.8.2005 */
  1420.       {    
  1421.     int readahead_result,fd;
  1422.     struct stat buf;
  1423.     size_t filesize;
  1424.     
  1425.     show_readahead_window(table);
  1426.     while (gtk_events_pending())
  1427.       gtk_main_iteration();
  1428.     if (F_START) {
  1429.       fd = fileno(startfile[table]); 
  1430.       fstat(fd, &buf);
  1431.       filesize = (size_t)buf.st_size; 
  1432.       readahead_result = readahead(fd,(loff_t)0,filesize); 
  1433.       if(readahead_result == -1) perror("readahead"); 
  1434.     }
  1435.     if (F_END) {
  1436.       fd = fileno(endfile[table]);
  1437.       fstat(fd, &buf);
  1438.       filesize = (size_t)buf.st_size;
  1439.       readahead_result = readahead(fd,(loff_t)0,filesize);
  1440.       if(readahead_result == -1) perror("readahead");    
  1441.     }
  1442.     if (F_INDEX) {
  1443.       fd = fileno(indexfile[table]);
  1444.       fstat(fd, &buf);
  1445.       filesize = (size_t)buf.st_size;
  1446.       readahead_result = readahead(fd,(loff_t)0,filesize);
  1447.       if(readahead_result == -1) perror("readahead");
  1448.     }
  1449.     
  1450.     hide_readahead_window();
  1451.       }
  1452.     /* end readahead */
  1453. #elif defined(WIN32)
  1454.     {
  1455.       long size;
  1456.       DWORD dwRead;
  1457.       
  1458.       show_readahead_window(table);
  1459.       while (gtk_events_pending())
  1460.     gtk_main_iteration();
  1461.       
  1462.       if (F_START) {
  1463.     size = GetFileSize(startfile[table], NULL);
  1464.     if (startbuff[table] = (unsigned char*) malloc (size))
  1465.       ReadFile(startfile[table], startbuff[table], size, &dwRead, NULL);
  1466.     else
  1467.       F_START = 0;
  1468.       }
  1469.       if (F_END) {
  1470.     size = GetFileSize(endfile[table], NULL);
  1471.     if (endbuff[table] = (unsigned char*) malloc (size))
  1472.       ReadFile(endfile[table], endbuff[table], size, &dwRead, NULL);
  1473.     else
  1474.       F_END = 0;
  1475.       }
  1476.       if (F_INDEX) {
  1477.     size = GetFileSize(indexfile[table], NULL);
  1478.     if (indexbuff[table] = (unsigned char*) malloc (size))
  1479.       ReadFile(indexfile[table], indexbuff[table], size, &dwRead, NULL);
  1480.     else
  1481.       F_INDEX = 0;
  1482.       }
  1483.       hide_readahead_window();
  1484.     }    
  1485. #endif    
  1486.     
  1487.     
  1488.     /* for each column of the tables */
  1489.     for (k=cols-1; k>=0; k--) {
  1490.       
  1491.       /* if (!quiet)
  1492.      if (!(k%display_step)) 
  1493.       display (-2,k);
  1494.       */
  1495.       update_statusbar(k);
  1496.  
  1497.       /* for each file containing a table: */
  1498.       for (table=first_table; table<=last_table; table++) {
  1499.     while (gtk_events_pending ()) {
  1500.       if (STOP) {
  1501.         close_files();
  1502.         return (0);
  1503.       }    
  1504.       gtk_main_iteration ();
  1505.     }
  1506.  
  1507.     /* for each password: */
  1508.     for (h=0; h<hashes || !to_go; h++) {
  1509.       if (!crack_type_num) { //LM CRACK
  1510.         if (!done1[h]) {
  1511.           n_search++;
  1512.           if (find(lm_hash1[h], password1[h], k, table)) {
  1513.         change_tree(h); 
  1514.         to_go--;
  1515.         done1[h]=1;
  1516.         if (done2[h]) {
  1517.           if (done_nt[h] || resolve_nt_hash(password1[h],password2[h],(char *)nt_hash[h],password[h])) 
  1518.             {n_found++; to_go--; done_nt[h]=1;}
  1519.           change_tree(h); 
  1520.           //display(h,k);
  1521.           update_statusbar(k);
  1522.         }
  1523.         if (!to_go) break; 
  1524.           }
  1525.         }
  1526.         
  1527.         if (!done2[h]) {
  1528.           n_search++;
  1529.           if (find(lm_hash2[h], password2[h], k, table)) {
  1530.         change_tree(h);
  1531.         done2[h]=1;
  1532.         to_go--;
  1533.         if (done1[h]) {
  1534.           if (done_nt[h] || resolve_nt_hash(password1[h],password2[h],(char *)nt_hash[h],password[h])) 
  1535.             {n_found++; to_go--; done_nt[h]=1;}
  1536.           change_tree(h);
  1537.           //display(h,k);
  1538.           update_statusbar(k);}
  1539.         if (!to_go) break; 
  1540.           }
  1541.         }
  1542.       } else { //NT CRACK
  1543.         if (!done_nt[h]) {
  1544.           n_search++;
  1545.           if (find(nt_hash[h], password[h], k, table)) {
  1546.         change_tree(h); 
  1547.         done_nt[h]=1;
  1548.         n_found++;
  1549.         to_go--;
  1550.         update_statusbar(k);
  1551.         if (!to_go) break; 
  1552.           }
  1553.         }
  1554.       }
  1555.     }
  1556.     if (!to_go) break;
  1557.       }
  1558.       if (!to_go) break;
  1559.     }
  1560.     if (!to_go) break;
  1561.   }
  1562.   
  1563.   /* display hashes that have not been fully cracked: */
  1564.   for (h=0; h<hashes;h++) 
  1565.     if (!done1[h] || !done2[h] || !done_nt[h]){
  1566.       if (!done1[h]) strcpy(password1[h],".......");
  1567.       if (!done2[h]) strcpy(password2[h],".......");
  1568.       if (!done_nt[h]) strcpy(password[h], "Not found");
  1569.       fill_tree();
  1570.     }
  1571.  
  1572.   print_stats();
  1573.   close_files();
  1574.   return (1); 
  1575. }
  1576.